﻿using gixoom.Dom.Block;
using gixoom.Initiator.WcfWsHttp;
using Ninject;

namespace gixoom.Dom.Storage.Block
{
    internal class BlockStorageFacade: IBlockStorageFacade
    {
        private IKernel kernel;
        private IgixoomWcfWsHttpInitiatorFacade wcfWsHttpInitiatorFacade;

        /// <summary>
        /// Creates BlockStorageFacade object.
        /// </summary>
        /// <param name="kernel">kernel</param>
        /// <param name="wcfWsHttpInitiatorFacade">WCF WsHttp initiator facade</param>
        /// <exception cref="System.ArgumentNullException">One of the arguments is a null reference.</exception>
        public BlockStorageFacade(IKernel kernel,
            IgixoomWcfWsHttpInitiatorFacade wcfWsHttpInitiatorFacade)
        {
            Ensure.ArgumentNotNull(kernel, "kernel");
            Ensure.ArgumentNotNull(wcfWsHttpInitiatorFacade, "wcfWsHttpInitiatorFacade");

            this.kernel = kernel;
            this.wcfWsHttpInitiatorFacade = wcfWsHttpInitiatorFacade;
        }

        /// <summary>
        /// Creates source block storage using the specified host addresses.
        /// </summary>
        /// <param name="addresses">host addresses</param>
        /// <returns>created source block storage</returns>
        /// <exception cref="System.ArgumentNullException"><i>addresses</i> is a null reference.
        /// </exception>
        /// <exception cref="System.ArgumentException"><i>addresses</i> length is too short.</exception>
        public IBlockStorage CreateSourceBlockStorage(string[] addresses)
        {
            Ensure.ArgumentNotNull(addresses, "addresses");
            Ensure.EnoughItems(addresses, 1, "addresses");

            var initiatorBlockStorages = new IInitiatorBlockStorage[addresses.Length];
            int i = 0;

            foreach (string address in addresses)
            {
                var initiatorBlockStorage = wcfWsHttpInitiatorFacade.CreateInitiatorBlockStorage(
                    address);
                initiatorBlockStorage.OpenConnection();
                initiatorBlockStorages[i++] = initiatorBlockStorage;
            }

            var sourceBlockStorage = kernel.Get<ISourceBlockStorage>();
            sourceBlockStorage.SetInitiatorBlockStorages(initiatorBlockStorages);

            return sourceBlockStorage;
        }

        /// <summary>
        /// Creates files block storage object.
        /// </summary>
        /// <param name="filesPath">the files path</param>
        /// <returns>created files block storage object</returns>
        /// <exception cref="System.ArgumentNullException"><i>filesPath</i> is a null reference</exception>
        /// <exception cref="System.ArgumentException"><i>filesPath</i> is an empty string.</exception>
        public IBlockStorage CreateFilesBlockStorage(string filesPath)
        {
            Ensure.ArgumentNotNull(filesPath, "filesPath");
            Ensure.StringArgumentNotEmpty(filesPath, "filesPath");

            var blockFacade = kernel.Get<IBlockFacade>();
            var blockStorage = new FilesBlockStorage(filesPath, blockFacade);

            return blockStorage;
        }
    }
}
